<?php

class Response
{
    private $statusCode;
    private $headers;
    private $body;
    /**
     * @var string 请求类型
     */
    private string $contentType;
    /**
     * @var string 字符集
     */
    private string $charset = 'utf-8';
    /**
     * @var array<Cookie> cookie列表
     */
    private array $cookies;

    public function __construct()
    {
        $this->statusCode = 200;
        $this->headers = [];
        $this->body = '';
    }

    /**
     * 设置响应码
     * @param $code string cookie的key
     * @return void 无返回值
     */
    public function setStatusCode($code)
    {
        $this->statusCode = $code;
    }

    /**
     * 添加header
     * @param $name string cookie的key
     * @param $value string cookie的值
     * @return void 无返回值
     */
    public function addHeader($name, $value)
    {
        $this->headers[$name] = $value;
    }

    /**
     * 移除header
     * @param $name string header的key
     * @return void 无返回值
     */
    public function removeHeader(string $name)
    {
        unset($this->headers[$name]);
    }

    /**
     * 设置Content-Type
     * @param string $contentType
     * @return void
     */
    public function setContentType(string $contentType)
    {
        $this->contentType = $contentType;
        $this->addHeader('Content-Type', $contentType . '; charset=' . $this->charset);
    }

    /**
     * 设置字符集
     * @param string $charset
     * @return void
     */
    public function setCharset(string $charset)
    {
        $this->charset = $charset;
    }

    /**
     * 重定向
     * @param string $url 跳转的url
     * @return void  无返回值
     */
    public function redirect(string $url)
    {
        if (empty($url)) {
            throw new InvalidArgumentException('URL cannot be empty.');
        }

        $this->setStatusCode(302);
        $this->addHeader('Location', $url);
        $this->send();
    }

    /**
     * 设置刷新
     * @param int $interval 刷新间隔，单位秒
     * @param string $url 刷新的url
     * @return void 无返回值
     */
    public function setRefresh(int $interval, string $url = '')
    {
        $refreshValue = $interval;
        if (!empty($url)) {
            $refreshValue .= ';url=' . $url;
        }
        $this->addHeader('Refresh', $refreshValue);
    }

    /**
     * 设置Content-Length
     * @param int $length
     * @return void
     */
    public function setContentLength(int $length)
    {
        $this->addHeader('Content-Length', $length);
    }

    /**
     * 设置响应体
     * @param $body
     * @return void
     */
    public function setBody($body)
    {
        $this->body = $body;
    }

    /**
     * 清空响应体
     */
    public function clearBody(){
        $this->body = '';
    }

    /**
     * 添加cookie
     * @param Cookie $cookie
     * @return void
     */
    public function addCookie(Cookie $cookie)
    {
        $this->cookies[] = $cookie;
    }

    /**
     * 添加多个cookie
     * @param array<Cookie> $cookies
     * @return void
     */
    public function addCookies(array $cookies):void
    {
        foreach ($cookies as $cookie) {
            $this->addCookie($cookie);
        }
    }

    /**
     * 移除cookie
     * @param string $name
     * @return void
     */
    public function removeCookie(string $name)
    {
        foreach ($this->cookies as $index => $cookie) {
            if ($cookie->getName() === $name) {
                unset($this->cookies[$index]);
                break;
            }
        }
    }

    /**
     * 发送整个响应请求
     * @return void
     */
    public function send()
    {
        // 设置响应码
        http_response_code($this->statusCode);

        // 添加cookie
        if (isset($this->cookies)) {
            foreach ($this->cookies as $cookie) {
                setcookie(
                    $cookie->getName(),
                    $cookie->getValue(),
                    $cookie->getExpires(),
                    $cookie->getPath(),
                    $cookie->getDomain(),
                    $cookie->isSecure(),
                    $cookie->isHttpOnly());
            }
        }

        // 添加响应头
        if (isset($this->headers)){
            foreach ($this->headers as $name => $value) {
                header("$name: $value");
            }
        }


        // 输出响应体
        echo $this->body;
    }

}